#include "RequestDispatcher.h"

RequestDispatcher::RequestDispatcher(void)
{
	
}

RequestDispatcher::~RequestDispatcher(void)
{
	
}

void RequestDispatcher::PushRequest(IRequest *aRequest)
{
	mMutex.lock();
		mRequests.push_back(aRequest);
	mMutex.unlock();
}

void RequestDispatcher::Tick()
{
	while(!mWorkerThread.interruption_requested())
	{
		mMutex.lock();
			if(mRequests.empty() != true)
			{
				RunRequests();
				EmptyRequests();
			}
		mMutex.unlock();
	}
}

void RequestDispatcher::TickNoThread()
{
	mMutex.lock();
		RunRequests();
		EmptyRequests();
	mMutex.unlock();
}

// Check for those not started here.
void RequestDispatcher::RunRequests()
{
	if(mRequests.empty() != true)
	{
		for(auto it = mRequests.begin(); it != mRequests.end(); ++it)
		{
			if((*it)->IsStarted() == false)
			{
				(*(*it))();
			}
		}
	}
}

// Check for those started, but not running here
// Also end threads which are taking too long to process
void RequestDispatcher::EmptyRequests()
{
	if(mRequests.empty() != true)
	{
		for(auto it = mRequests.begin(); it != mRequests.end(); ++it)
		{
			if(((*it)->IsStarted() == true) && ((*it)->IsRunning() == false))
			{
				// Thread Stopped. Hopefully all cleaned up too.
				delete (*it);
				mRequests.erase(it);
				// Since we're editing the vector it's best just to give up and break here.
				// We'll catch others next loop
				break;
			}
		}
	}
}

void RequestDispatcher::operator()(void)
{
	mWorkerThread = boost::thread(&RequestDispatcher::Tick, this);
}

void RequestDispatcher::Stop()
{
	mWorkerThread.interrupt();
}